// =====================================================================================
//
//       Filename:  parser.h
//
//    Description:  Définition de fonctions générales pour l'interprétation des fichiers
//					d'entrée
//
//        Version:  1.0
//        Created:  25/08/2009 17:01:45
//       Revision:  none
//       Compiler:  g++
//
//         Author:  François Hissel (fh), francois.hissel@m4x.org
//        Company:
//
// =====================================================================================

#ifndef PARSER_H_INC
#define PARSER_H_INC

#include	<iostream>
#include	<sstream>
#include	<string>
#include	<exception>

using namespace std;

/**
 * \class ParseException
 * \brief Exception soulevée lors d'une erreur rencontrée pendant l'interprétation d'une chaîne de caractères (\e parsing)
 *
 * La classe permet de gérer les erreurs rencontrées pendant l'interprétation d'une chaîne de caractères. Les fonctions de \e parsing sont principalement utilisées pour la lecture des fichiers de configuration ou des commandes de l'utilisateur.
 */
class ParseException:public exception {
	public:
		/**
		 * \brief Ensemble des codes d'erreur possibles
		 *
		 * L'énumération rassemble les codes d'erreur qui peuvent être retournés lorsqu'une opération d'interprétation d'un flux de données a généré une erreur.
		 */
		enum Code {
			FORMAT_ERROR	//!< Format de données incorrect
			} code;	//!< Code de l'erreur
		string message;	//!< Message décrivant l'erreur
		ParseException(Code pcode):code(pcode),message("") {}	//!< Constructeur standard sans message d'erreur
		ParseException(Code pcode,string pmessage):code(pcode),message(pmessage) {}	//!< Constructeur standard avec message d'erreur
		~ParseException() throw() {}	//!< Destructeur standard
		const char* what() const throw();	//!< Retourne la nature de l'erreur
};

/**
 * \fn int getint(const string &line,size_t &pos,char delim=',')
 * \brief Lit un entier à partir d'une chaîne de caractères
 *
 * La fonction lit un entier à partir d'une chaîne de caractères en commençant à la position spécifiée, et en s'arrêtant au délimiteur.
 * \param line Chaîne de caractères à lire
 * \param &pos Numéro du premier caractère à lire, la valeur sera mise à jour et pointera sur le premier caractère après le séparateur
 * \param delim Délimiteur de séparation des valeurs
 * \return Entier lu dans la chaîne
 */
int getint(const string &line,size_t &pos,char delim=',') throw (ParseException);

/**
 * \fn int getfloat(const string &line,size_t &pos,char delim=',')
 * \brief Lit un flottant à partir d'une chaîne de caractères
 *
 * La fonction lit un flottant à partir d'une chaîne de caractères en commençant à la position spécifiée, et en s'arrêtant au délimiteur.
 * \param line Chaîne de caractères à lire
 * \param &pos Numéro du premier caractère à lire, la valeur sera mise à jour et pointera sur le premier caractère après le séparateur
 * \param delim Délimiteur de séparation des valeurs
 * \return Flottant lu dans la chaîne
 */
double getfloat(const string &line,size_t &pos,char delim=',') throw (ParseException);

/**
 * \fn string getstring(const string &line,size_t &pos,char delim=',')
 * \brief Lit une chaîne de caractères dans une ligne
 *
 * La fonction lit une chaîne de caractères délimitée par des guillemets à partir d'une autre chaîne de caractères en commençant à la position spécifiée, et en s'arrêtant au délimiteur
 * \param line Chaîne de caractères à lire
 * \param &pos Numéro du premier caractère à lire, la valeur sera mise à jour et pointera sur le premier caractère après le séparateur
 * \param delim Délimiteur de séparation des valeurs
 * \return Chaîne lue
 */
string getstring(const string &line,size_t &pos,char delim=',') throw (ParseException);

/**
 * \fn bool string_compare(const string &s1,const string &s2,size_t debut,size_t longueur)
 * \brief Compare deux chaînes de caractères en ne tenant pas compte de la casse
 *
 * La fonction est une extension de la fonction String::compare. Elle compare les deux chaînes de caractères s1 et s2, mais sans tenir compte de la casse, en commençant à la position debut et pour un nombre de caractères égal à longueur.
 * La fonction retourne Vrai si les chaînes sont égales, Faux si elles sont différentes.
 * \param s1 Première chaîne de caractères à comparer
 * \param s2 Seconde chaîne de caractères à comparer
 * \param debut Indique la position dans la chaîne s2 où commencera la comparaison. Celle-ci commence toujours au début de la chaîne s1.
 * \param longueur Indique le nombre de caractères à comparer
 * \return true si les deux chaînes sont égales, false sinon.
 */
bool string_compare(const string &s1,const string &s2,size_t debut,size_t longueur);

/**
 * \fn bool string_compare(const string &s1,const string &s2)
 * \brief Compare deux chaînes de caractères en ne tenant pas compte de la casse
 *
 * La fonction est une extension de la fonction String::compare. Elle compare les deux chaînes de caractères s1 et s2, mais sans tenir compte de la casse. Si les deux chaînes n'ont pas le même nombre de caractères, la fonction retourne Faux.
 * La fonction retourne Vrai si les chaînes sont égales, Faux si elles sont différentes.
 * \param s1 Première chaîne de caractères à comparer
 * \param s2 Seconde chaîne de caractères à comparer
 * \return true si les deux chaînes sont égales, false sinon.
 */
bool string_compare(const string &s1,const string &s2);

/**
 * \fn string trim(const string& s)
 * \brief Supprime les espaces au début et à la fin de la chaîne de caractères passée en argument
 *
 * La fonction retourne une copie de la chaîne de caractères s dans laquelle les espaces blancs (espaces et tabulations) initiaux et finaux ont été supprimés.
 */
string trim(const string& s);

#endif /* PARSER_H_ */
